home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / ctask.zip / TSKTIM.ASM < prev    next >
Assembly Source File  |  1988-07-01  |  5KB  |  256 lines

  1. ;
  2. ;    CTask - Timer interrupt handler (IBM specific)
  3. ;
  4. ;    Public Domain Software written by
  5. ;        Thomas Wagner
  6. ;        Patschkauer Weg 31
  7. ;        D-1000 Berlin 33
  8. ;        West Germany
  9. ;
  10.     name    tsktim
  11.     .model    large
  12. ;
  13.     public    _tsk_install_timer
  14.     public    _tsk_remove_timer
  15.     public    _tsk_chain_timer
  16. ;
  17.     include    tsk.mac
  18. ;
  19. timer    equ    40h            ; 8253 timer base I/O address
  20. inta00    equ    20h            ; 8259 int controller base
  21. eoi    equ    20h            ; unspecific EOI
  22. ;
  23. intseg    segment at 0
  24. ;
  25.         org    8*4
  26. tintofs        dw    ?        ; timer interrupt entry
  27. tintseg        dw    ?
  28.  
  29. intseg    ends
  30. ;
  31. ;
  32.     .data?
  33. ;
  34.     extrn    _tsk_timer_counter:word
  35.     extrn    _tsk_int9_counter:word
  36. ;
  37. divisor        dw    ?
  38. timflag        dw    ?
  39. timcnt        dw    ?
  40. sys_ticks    dw    ?
  41. ;
  42.     .code
  43. ;
  44.     extrn    _sched_int: far
  45.     extrn    _inc_counter: far
  46. ;
  47. timer_save    label    dword        ; in CSEG to allow addressing
  48. tsofs        dw    ?
  49. tsseg        dw    ?
  50. ;
  51. ;----------------------------------------------------------------------
  52. ;
  53. ;    timer interrupt handler
  54. ;
  55. timer_int    proc    far
  56.     sti
  57.     push    ds
  58.     push    ax
  59.     mov    ax,SEG dgroup
  60.     mov    ds,ax
  61. ;
  62.     cmp    timflag,1        ; initialisation ?
  63.     jne    no_init
  64. ;
  65. ;    Install timer
  66. ;
  67.     mov    timflag,0        ; signal init ready
  68.     mov    timcnt,1
  69.     mov    al,36h
  70.     out    timer+3,al        ; setup to load divisor
  71.     mov    al,byte ptr divisor
  72.     out    timer,al        ; lsb
  73.     mov    al,byte ptr divisor+1
  74.     out    timer,al        ; msb
  75.     jmp    short no_uninit
  76. ;
  77. no_init:
  78.     cmp    timflag,2        ; un-install flag set?
  79.     jne    no_uninit        ; no un-install if not
  80. ;
  81. ;       Un-Install timer (wait until system tick count reached)
  82. ;
  83. timdec:
  84.     cli
  85.     dec    timcnt            ; decrement tick count
  86.     jz    uninit            ; go un-install if zero
  87.     mov    al,eoi            ; else just issue EOI
  88.     out    inta00,al
  89.     pop    ax
  90.     pop    ds
  91.     iret                ; do nothing while waiting for uninit
  92. ;
  93. ;--------------------------------------------------------------------
  94. ;
  95. ;    Normal timer tick. The tick counter is incremented, and
  96. ;    the interrupt controller is checked for other pending interrupts.
  97. ;    If the timer tick occurred during processing of another interrupt,
  98. ;    we may not call the scheduler, since this would delay the
  99. ;    interrupt handler.
  100. ;
  101. ;    Note that an EOI is issued here to allow interrupts to occur
  102. ;    during further processing. The original INT 9 handler will be
  103. ;    chained to from a special task. The reason behind this is that
  104. ;    some TSR's link into the timer interrupt and may do some lengthy
  105. ;    processing there. To allow the TSR to be preempted, we must use
  106. ;    a task for the INT 9 processing.
  107. ;
  108. no_uninit:
  109.     push    es            ; save other regs
  110.     push    bx
  111.     push    cx
  112.     push    dx
  113.     mov    ax,ds
  114.     mov    es,ax
  115.     mov    ax,offset _tsk_timer_counter
  116.     push    ds
  117.     push    ax
  118.     call    _inc_counter        ; increase timer tick counter
  119.     add    sp,4
  120. ;
  121. ;    Now the timer counter is decremented. If it is zero,
  122. ;    we must chain to the original INT 9, so the counter for
  123. ;    the chain task is incremented.
  124. ;
  125.     dec    timcnt            ; decrement tick count
  126.     jnz    no_pass            ; pass on this int if zero
  127. ;
  128.     mov    ax,sys_ticks
  129.     mov    timcnt,ax        ; re-init tick counter
  130. ;
  131.     mov    ax,offset _tsk_int9_counter
  132.     push    ds
  133.     push    ax
  134.     call    _inc_counter        ; increase timer tick counter
  135.     add    sp,4
  136. ;
  137. no_pass:
  138.     pop    dx
  139.     pop    cx
  140.     pop    bx
  141.     pop    es
  142. ;
  143.     cli
  144.     mov    al,eoi            ; issue EOI
  145.     out    inta00,al
  146.     mov    al,0bh            ; access int control reg
  147.     out    inta00,al
  148.     in    al,inta00        ; ints pending?
  149.     or    al,al
  150.     pop    ax
  151.     pop    ds
  152.     jnz    no_sch            ; don't schedule if other ints active
  153.     jmp    _sched_int        ; else schedule
  154. ;
  155. no_sch:
  156.     iret
  157. ;
  158. ;------------------------------------------------------------------------
  159. ;
  160. ;    Uninstall timer int handler
  161. ;
  162. uninit:
  163.     mov    timflag,0        ; mark un-install complete
  164.     mov    al,36h            ; setup to load divisor
  165.     out    timer+3,al
  166.     mov    al,0            ; divisor 0 means 65536
  167.     out    timer,al        ; lsb
  168.     out    timer,al        ; msb
  169.     push    es
  170.     xor    ax,ax
  171.     mov    es,ax
  172.     assume    es:intseg
  173.     mov    ax,cs:tsofs        ; restore vector
  174.     mov    tintofs,ax
  175.     mov    ax,cs:tsseg
  176.     mov    tintseg,ax
  177.     assume    es:nothing
  178.     pop    es
  179.     pop    ax
  180.     pop    ds
  181.     jmp    cs:timer_save        ; pass on interrupt
  182. ;
  183. timer_int    endp
  184. ;
  185. ;----------------------------------------------------------------------
  186. ;
  187. ;    void far tsk_chain_timer (void)
  188. ;
  189. ;       Pass timer tick on to interrupt 9 chain.
  190. ;
  191. _tsk_chain_timer    proc    far
  192. ;
  193.     pushf
  194.     cli
  195.     call    cs:timer_save
  196.     ret
  197. ;
  198. _tsk_chain_timer    endp
  199. ;
  200. ;
  201. ;    void far tsk_install_timer (word divisor, word sys_ticks)
  202. ;
  203. ;    This routine installs the timer tick int handler.
  204. ;    The timer chip is reprogrammed on the next tick.
  205. ;
  206. _tsk_install_timer    proc    far
  207. ;
  208.     push    bp
  209.     mov    bp,sp
  210.     mov    ax,6[bp]
  211.     mov    divisor,ax
  212.     mov    ax,8[bp]
  213.     mov    sys_ticks,ax
  214.     mov    timflag,1        ; set init-flag
  215.     xor    ax,ax
  216.     mov    es,ax            ; establish addressing for intseg
  217.     assume    es:intseg
  218. ;
  219.     mov    ax,tintofs        ; save old timer int addr
  220.     mov    tsofs,ax
  221.     mov    ax,tintseg
  222.     mov    tsseg,ax
  223.     cli
  224.     mov    tintofs,offset timer_int ; set new timer int addr
  225.     mov    tintseg,cs
  226.     sti
  227.     assume    es:nothing
  228. wait_set:
  229.     cmp    timflag,0        ; wait until timer started
  230.     jne    wait_set
  231.     pop    bp
  232.     ret
  233. ;
  234. _tsk_install_timer    endp
  235. ;
  236. ;
  237. ;    void far tsk_remove_timer (void)
  238. ;
  239. ;    This routine un-installs the timer tick int handler.
  240. ;    The timer chip is reprogrammed & the interrupt vector
  241. ;    restored when the system tick count reaches zero.
  242. ;
  243. _tsk_remove_timer    proc    far
  244. ;
  245.     mov    timflag,2        ; set un-init flag for timer
  246. wait_tim:
  247.         sti                             ; just to be safe
  248.     cmp    timflag,0        ; wait until int un-installed
  249.     jne    wait_tim
  250.     ret
  251. ;
  252. _tsk_remove_timer    endp
  253. ;
  254.     end
  255.  
  256.